#include "schedule.h"
#include "project.h"

//#include "usb_device.h"
//#include "usbd_hid.h"

// 选择性开关宏
//#define __USB_HID_MOUSE__
//#define __USB_HID_KEYBOARD__

//extern USBD_HandleTypeDef hUsbDeviceFS;

unsigned char uart1Data;
unsigned short uart1RxBufferLen = 0;
unsigned char uart1RxBuffer[120] = {0};
unsigned char generalBuffer[120] = {0};
int UserOperateType;
int UserOperateValue;

unsigned int rxCnt = 0;
unsigned char fileBuffer[20 * 1024] = {0};
//unsigned char fileBuffer[2] = {0};

extern unsigned char g_hmc5883Data[10];
extern I2C_HandleTypeDef hi2c1;
extern I2C_HandleTypeDef hi2c2;

extern ADC_HandleTypeDef hadc1;

float Pitch,Roll,Yaw;

// 重定向fputc，实现printf
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch,FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
	while((huart1.Instance->SR & 0x40) == 0);
	huart1.Instance->DR = (uint8_t)ch;
	return ch;
}

void Task1ms(void)
{
	ANO_DT_Data_Exchange();

}
void Task5ms(void)
{

}

void LedTask(void)
{
	HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
}


void KeyTask(void)
{
	VtorKey_Scan(10);

#ifdef __USB_HID_KEYBOARD__
	unsigned char keyboardBuf[] = {0,0,0,0,0,0,0,0};
	if (VTOR_KEY_COMBINE_SHORT_CLICK == combineAction)
	{
		keyboardBuf[2] = 0x04; // 对应  a ,,就是输入一个    a
		//sprintf((char*)generalBuffer, "key1:%d, keyboard", combineState);
		//OLED_PushLog(generalBuffer);
	}
	if (VTOR_KEY_COMBINE_SS_CLICK == combineAction)
	{
		keyboardBuf[0] = 0x01; // 对应  CTRL
		keyboardBuf[2] = 0x06; // 对应  C
		//sprintf((char*)generalBuffer, "key1:%d, keyboard", combineState);
		//OLED_PushLog(generalBuffer);
	}
	if (VTOR_KEY_COMBINE_SSS_CLICK == combineAction)
	{
		keyboardBuf[0] = 0x01; // 对应  CTRL
		keyboardBuf[2] = 0x19; // 对应  V
		//sprintf((char*)generalBuffer, "key1:%d, keyboard", combineState);
		//OLED_PushLog(generalBuffer);
	}
	USBD_HID_SendReport(&hUsbDeviceFS, keyboardBuf, sizeof(keyboardBuf) / sizeof(keyboardBuf[0]));
#endif
#ifdef __USB_HID_MOUSE__
	// 可以使用while1进行死循环，建议加一点延时，在diaan工程中，会10ms调用此函数
	// 鼠标工程
	/*
	usb中文网中有介绍
	https://usbzh.com/article/detail-327.html
	鼠标发送给PC的数据每次4个字节。
	BYTE1字节：
			bit7～3：补充的常数，无意义，这里为0即可
			bit2: 1表示中键按下
			bit1: 1表示右键按下 0表示右键抬起
			bit0: 1表示左键按下 0表示左键抬起
	BYTE2 — X坐标变化量，与byte的bit4组成9位符号数,负数表示向左移，正数表右移。用补码表示变化量
	BYTE3 — Y坐标变化量，与byte的bit5组成9位符号数，负数表示向下移，正数表上移。用补码表示变化量
	BYTE4 — 滚轮变化。0x01表示滚轮向前滚动一格；0xFF表示滚轮向后滚动一格；0x80是个中间值，不滚动。
	 * */

	 // 每隔10ms调用一次此函数
	unsigned char mouseBuf[] = {0,100,100,0}; // 代表鼠标向右  移动100像素点，，，，向下移动100像素点
	if (VTOR_KEY_COMBINE_NULL != combineAction)
	{
		//sprintf((char*)generalBuffer, "key1:%d, keyboard", combineState);
		//OLED_PushLog(generalBuffer);
		USBD_HID_SendReport(&hUsbDeviceFS, mouseBuf, sizeof(mouseBuf) / sizeof(mouseBuf[0]));
	}

#endif

	//sprintf((char*)generalBuffer,"    %d\r\n",combine);
	//HAL_UART_Transmit(&huart1, generalBuffer, strlen((char*)generalBuffer), 0XFF);
	//OLED_PushLog(generalBuffer);

}

void Qmc5883Task(void)
{
	Qmc5883_GetData();
	sprintf((char*)generalBuffer, "qmcBuffer %d %d %d %d %d %d",
			qmcBuffer[0],qmcBuffer[1],qmcBuffer[2],qmcBuffer[3],qmcBuffer[4],qmcBuffer[5]);
	//OLED_PushLog(generalBuffer);
	//printf("%s\r\n",generalBuffer);

	sprintf((char*)generalBuffer, "qmcData %d %d %d -> %f\r\n",
			qmcData.x, qmcData.y, qmcData.z, qmcData.roll);
	OLED_PushLog(generalBuffer);
	printf("%s\r\n",generalBuffer);

}

void UartTask(void)
{
	if (uart1RxBufferLen & 0x8000)
	{
		HAL_UART_Transmit(&huart1, uart1RxBuffer, uart1RxBufferLen & 0x7fff,0XFF);
		HAL_UART_Transmit(&huart1, "----------start---------\r\n",strlen("----------start---------\r\n"),0XFF);
		// 根据前缀进入指定操作，有menu则进入菜单操作
		if (memcmp(uart1RxBuffer, "menu", 4) == 0)
		{
			UserOperateType = uart1RxBuffer[4] - '0';
			UserOperateValue = uart1RxBuffer[5] - '0';
			OLED_ClearGRam();
			VtorMenu_Operate(UserOperateType, UserOperateValue);
			VtorMenu_Display();
			OLED_Refresh();

			UserOperateType = 0;
		}
		else
		{
			//usmart_dev.scan();
		}
		// 用户操作完成，清空串口接收长度
		uart1RxBufferLen = 0;
		HAL_UART_Transmit(&huart1, "==========stop=========\r\n",strlen("==========stop=========\r\n"),0XFF);
	}
}


void OledTask(void)
{
	//sprintf((char*)generalBuffer, "OledTask %d",timer->runCnt);
	//OLED_PushLog(generalBuffer);


	LED1_Toggle();
	OLED_ClearGRam();
	VtorMenu_Display();
	OLED_Refresh();
}

void Mpu6050Task(void)
{

	//Read_DMP(&Pitch,&Roll,&Yaw);
	sprintf((char*)generalBuffer, "mpu6050 %f %f %f", Pitch,Roll,Yaw);
	OLED_PushLog(generalBuffer);

	float pwm = Pitch;
	if (-100 < pwm && pwm < -80)
	{
		pwm += 90; // +-10
		pwm *= 100;
		HAL_GPIO_WritePin(MOTOR_DIR_GPIO_Port, MOTOR_DIR_Pin , pwm < 0);
		if (pwm > 0)
		{
			pwm = pwm;
		}
		else
		{
			pwm = 1000 - pwm;
		}
		__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, pwm);
	}
	else
	{
		HAL_GPIO_WritePin(MOTOR_DIR_GPIO_Port, MOTOR_DIR_Pin , 0);
		__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, 0);
	}

	//printf("%s\r\n", generalBuffer);


	//MPU6050_Read(); 															//读取mpu6轴传感器

	//MPU6050_Data_Prepare( HAL_GetTick() );			//mpu6轴传感器数据处理
/*
	sprintf((char*)generalBuffer, "mpu%d %f %f %f",
			timer->runCnt,
			mpu6050.Gyro_deg.x,
			mpu6050.Gyro_deg.y,
			mpu6050.Gyro_deg.z);
	OLED_PushLog(generalBuffer);
	sprintf((char*)generalBuffer, "mpu offset %f %f %f %f",
			mpu6050.Acc_Offset.x,
			mpu6050.Acc_Offset.y,
			mpu6050.Acc_Offset.z,
			mpu6050.Temprea_Offset);
	OLED_PushLog(generalBuffer);
	*/
}


void BeepTask(void)
{
	Beep_PlayMusic(0);
}

void McuTempTask(void)
{
	uint32_t adcValue[4];
	float volt;
	float temperate;
	char i;
	for (i = 0; i < 4; i++)
	{
		HAL_ADC_Start(&hadc1);
		HAL_ADC_PollForConversion(&hadc1,10);
		adcValue[i] = HAL_ADC_GetValue(&hadc1);
		volt=(float)(adcValue[i]*3.3/4096);     //转为电压值
		temperate=(volt-0.76)/0.0025+25; 	// 将电压转换成温度值
	}
	//sprintf((char*)generalBuffer, "mcuTemp %d %f %f", adcValue, volt, temperate);
	sprintf((char*)generalBuffer, "mcuTemp %d %d %d %d", adcValue[0], adcValue[1], adcValue[2],adcValue[3]);
	OLED_PushLog(generalBuffer);
	printf("%s\r\n",generalBuffer);
}


void ShowProjInfo()
{
	sprintf((char*)generalBuffer,"%s\r\n",PROJECT_NAME);
	HAL_UART_Transmit(&huart1, generalBuffer, strlen((char*)generalBuffer), 0XFF);
	OLED_PushLog(generalBuffer);
	sprintf((char*)generalBuffer,"%s\r\n",__DATE__);
	HAL_UART_Transmit(&huart1, generalBuffer, strlen((char*)generalBuffer), 0XFF);
	OLED_PushLog(generalBuffer);
	sprintf((char*)generalBuffer,"%s\r\n",__TIME__);
	HAL_UART_Transmit(&huart1, generalBuffer, strlen((char*)generalBuffer), 0XFF);
	OLED_PushLog(generalBuffer);
}

void InitTask(void)
{
	ShowProjInfo();

	//VtorI2c_Init();
	//OLED_Init();
	VtorMenu_Init();
	VtorKey_Init();

	//HMC5883_Init();
	//MPU6050_Init(20);
	HAL_TIM_Base_Start_IT(&htim7);

	HAL_TIM_PWM_Start_IT(&htim2,TIM_CHANNEL_1);
	HAL_TIM_PWM_Start_IT(&htim2,TIM_CHANNEL_2);
	HAL_TIM_PWM_Start_IT(&htim2,TIM_CHANNEL_3);
	HAL_TIM_PWM_Start_IT(&htim2,TIM_CHANNEL_4);

	HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
	HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_2);
	HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_3);
	HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_4);

	HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);

	HAL_UART_Receive_IT(&huart1, &uart1Data, 1);

	ShowProjInfo();

	//MPU6050_initialize();     //=====MPU6050初始化
	//DMP_Init();

	HAL_ADC_Start(&hadc1);
	//u8 audio_mvol=30;//ÉùÒôµ÷½Ú0-63£¬Ä¬ÈÏÑ¡Ôñ30
	//u8 ret = WM8978_Init();
	//if(ret != 0)
	{
		//HAL_UART_Transmit(&huart1, "WM8978 Error!\r\n", 14, 0XFF);
	//	printf("WM8978 Error%d!\r\n",ret);
	//	OLED_PushLog("wm8978 error.");
	}
	VtorTimer_Start(Task1ms, 1);
	VtorTimer_Start(Task5ms, 5);
	VtorTimer_Start(UartTask, 100);
	VtorTimer_Start(LedTask, 1000);
	VtorTimer_Start(OledTask, 100);
	VtorTimer_Start(Mpu6050Task, 50);
	VtorTimer_Start(Qmc5883Task, 1000);
	VtorTimer_Start(BeepTask, 130);
	VtorTimer_Start(McuTempTask, 100);
	printf("UserInit finish.\r\n");
}

//void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
//{
//	if (htim == &htim7)
//	{
//		TS_TimeBase();
//	}
//}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if (huart == &huart1)
	{
		//ANO_DT_Data_Receive_Prepare(uart1Data);
		// 还处在接收状态，就接收数据
		if ((uart1RxBufferLen & 0x8000) == 0)
		{
			uart1RxBuffer[uart1RxBufferLen++] = uart1Data;

			if (('\n' == uart1Data)
				&& (uart1RxBufferLen > 2)
				&& ('\r' == uart1RxBuffer[uart1RxBufferLen - 2]))
			{
				// 接收到了一帧完整的，带有回车的数据，设置标志位
				uart1RxBufferLen |= 0x8000;
			}
		}
		HAL_UART_Receive_IT(&huart1, &uart1Data, 1);
	}
}

